#include <iostream>
#include <fstream>
#include "Globals.h"
#include "ThreadsPool.h"

#include <sys/stat.h>
#include <cstdlib>
#include <unistd.h>
#include <fcntl.h>

using namespace std;

/******* Definitions **************************/

#define MIN(i, j) ((i <= j) ? i : j)

/******* Data Types ***************************/

/******* Functions ****************************/


int main(int argc, char* argv[])
{
///	doneReadingFiles = false;
	/* read the configuration parameters */
	// first command line argument : number of threads
	maxThreads = atol(argv[1]);

	// second command line argument : window size
	minMatchLength = atol(argv[2]);
	windowSize = MIN(minMatchLength, 31);

	// third command line argument : reference sequence file
	ifstream refSeqFile(argv[3], ios::in);
	refSeqFile.seekg(0, std::ios::end);
	streampos refSeqFileLength = refSeqFile.tellg();
	refSeqFile.seekg(0, std::ios::beg);
	refSeq = new ReferenceSequence(refSeqFile, refSeqFileLength, windowSize);

#ifdef DEBUG
	//refSeq->print();
	cout << endl << "******************* Done with reference sequence ********************" << endl;
#endif /* DEBUG */
	
	// create space for all structures needed to hold results
	numOfFiles = argc - 4;
/*
	results = new vector<Match>*[numOfFiles];
	names = new vector<Name>*[numOfFiles];
	beginStrs = new char**[numOfFiles];
	
	for (uint i = 0; i < numOfFiles; i++)
	{
		results[i] = new vector<Match>[maxThreads];
		names[i] = new vector<Name>[maxThreads];
		beginStrs[i] = new char*[maxThreads];
	}
*/	
	// open all files and create the FileData array
	struct stat st;
	files = new FileData*[numOfFiles];
	for (uint i = 0; i < numOfFiles; i++)
	{
		int fd = open(argv[4+i], O_RDONLY);
		if (fd == -1)
		{
			perror("Error reading reference file");
			exit(1);
		}
		stat(argv[4+i], &st);
		files[i] = new FileData(fd, argv[4+i], st.st_size);
	}
	
	pool = new ThreadsPool();
	
	pool->runMainThread();

	pool->waitThreads();
	
	for (uint i = 0; i < numOfFiles; i++)
	{
		delete files[i];
	}
	delete[] files;

///	for (uint i = 0; i < numOfFiles; i++)
///	{
///		delete results[i] ;
///		delete names[i];
///		delete beginStrs[i]; /* May cause segmentation falut!!! */
///	}
	
///	delete results;
///	delete names;
///	delete beginStrs;
	delete refSeq;

	return 0;
}


